﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using blackhouse.WebNemo.Business.Groups;

namespace blackhouse.WebNemo.Mvc.Controllers {
    public class NemoController : Controller {

        #region Actions

        public ActionResult PreviewFile(int id, int groupId, string column, Size size, int cache = 1) {
            var file = new RecordFile(groupId, column, id);
            if (!file.Exist) return new HttpNotFoundResult();
            var requestTag = Request.Headers["If-None-Match"];
            if (cache == 1 && !String.IsNullOrEmpty(requestTag) && requestTag.Equals(file.FileGuid.ToString()))
                return new HttpStatusCodeResult(304, "Not Modified");
            Response.Cache.SetETag(file.FileGuid.ToString());
            Response.Cache.SetCacheability(HttpCacheability.Public);
            var extension = GetFileExtension(file.FileName);
            var imageFormat = GetImageFormat(extension);
            var data = file.GetData();
            if (!size.Equals(Size.Empty))
                data = Resize(data, size, imageFormat);
            return File(data, "image/" + extension);
        }

        #endregion

        #region Methods

        private ImageFormat GetImageFormat(string fileExtension) {
            ImageFormat format = null;
            switch (fileExtension) {
                case "gif": format = ImageFormat.Gif; break;
                case "png": format = ImageFormat.Png; break;
                default: format = ImageFormat.Jpeg; break;
            }
            return format;
        }

        private static byte[] Resize(byte[] fileData, Size newSize, ImageFormat imageFormat) {
            using (var ms = new MemoryStream()) {
                ms.Write(fileData, 0, fileData.Length);
                var image = Image.FromStream(ms);
                newSize = SizeOfResizedImage(image.Size, newSize);
                using (var thumb = new Bitmap(newSize.Width, newSize.Height))
                using (var gp = Graphics.FromImage(thumb)) {
                    gp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    gp.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    gp.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                    gp.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    gp.DrawImage(image, 0, 0, newSize.Width, newSize.Height);
                    using (var msOut = new MemoryStream()) {
                        thumb.Save(msOut, imageFormat);
                        return msOut.ToArray();
                    }
                }
            }
        }

        private static Size SizeOfResizedImage(Size currentSize, Size newSize) {
            if (newSize.IsEmpty) return newSize;
            if (currentSize.Width <= newSize.Width || currentSize.Height <= newSize.Height) return currentSize;
            var resizeW = 1d * newSize.Width / currentSize.Width;
            var resizeH = 1d * newSize.Height / currentSize.Height;
            int nw, nh;
            if (resizeW > resizeH) {
                nw = newSize.Width;
                nh = (int)Math.Round(currentSize.Height * resizeW);
            } else {
                nh = newSize.Height;
                nw = (int)Math.Round(currentSize.Width * resizeH);
            }
            return new Size(nw, nh);
        }

        private static string GetFileExtension(string fileName) {
            if (String.IsNullOrEmpty(fileName) || !fileName.Contains(".")) return String.Empty;
            return fileName.Split('.').Last();
        }

        #endregion

    }
}